# -*- coding: utf-8 -*-
from django.http import HttpResponseRedirect
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.core.context_processors import csrf
from django.template import RequestContext
from django import forms
import logging
import sheetfetcher
from django.utils import simplejson
import time



class login_status():
    ok = 0
    failed = 1
    default = 2
    status = None


s = sheetfetcher.fetcher()
l = login_status()

class loginForm(forms.Form):
    id = forms.CharField(label=u'帳號', help_text=u'你的義勇隊號', min_length=5)
    passwd = forms.CharField(label=u'密碼', min_length=8,
            help_text = u'\
            預設密碼是西元的生日年份加身份證字號後四碼,\
            例如:19801234,1980是西元生日年份,1234是身份證後四碼\
            ')

def login(request):
    def returnError(request, form, error):
        return render_to_response('login.html',
                {
                    'form': form,
                    'error': error, 
                    },
                context_instance=RequestContext(request)
                )

    if request.method == 'POST': # If the form has been submitted...
        form = loginForm(request.POST) # A form bound to the POST data

        if not form.is_valid():
            return returnError(request, form, u'請檢查欄位')
        
        loginid = None
        
        try:
            loginid = (request.POST['id']).encode('ascii','ignore')
            user = s.get_user(loginid)
        except:
            raise
            l.status = l.failed
            return returnError(request, form, u'請稍候再登入一次')


        if( user == None ):
            return returnError(request, form, u'帳號或密碼錯誤')
        
        userid = user.get('id',None)
        userpw = user.get('passwd',None)

        logging.info('userid=%s' % userid)
        logging.info('userpw=%s' % userpw)

        if( (userid == None) or (userpw == None)  ):
            l.status = l.failed
            return returnError(request, form, u'帳號或密碼錯誤')
        
        # check passwd
        loginpw = (request.POST['passwd']).encode('ascii','ignore')

        # login with default passwd 
        if(loginpw == user['passwddefault']):
            l.status = l.default

            c = int(user.get('account_logincount','0')) + 1
            s.update_user({'account_logincount':c, 'account_loginfailcount':0}) 

            return render_to_response('system.html', 
                    {
                        'user':user,
                        'info':u'你使用了預設密碼登錄,請進入[更改密碼],更改預設密碼,再繼續使用系統',
                        },
                    context_instance=RequestContext(request)
                    ) 
        
        # login ok
        if(loginpw == userpw):
            l.status = l.ok

            c = int(user.get('account_logincount','0')) + 1
            s.update_user({'account_logincount':c, 'account_loginfailcount':0}) 

            return render_to_response('system.html', 
                    {
                        'user':user,
                        'default_disabled':'x', #FIXME?
                        },
                    context_instance=RequestContext(request)
                    ) 
        
       
        # login failed
        l.status = l.failed

        c = int(user.get('account_loginfailcount','0')) + 1
        s.update_user({'account_loginfailcount':c}) 

        
        logging.info(s.config['login']['max_failed_count'])

        error = ''
        info = ''

        if c > int(s.config['login']['max_failed_count']):
            error = u'錯誤太多次,帳號已經鎖定,無法再次登入,請與文宣組聯絡'
            disabled = 'disabled=\"disabled\"'

        elif c > int(s.config['login']['max_show_passwd_hint']) and 'passwdhint' in s.user:
            info = u'密碼提示: %s' % s.user['passwdhint']
            disabled = ' '
        
        else:
            error = u'帳號或密碼錯誤'
            disabled = ' '

        return render_to_response('login.html',
                {
                    'form': form,
                    'error': error,
                    'info': info,
                    'disabled': disabled,
                    },
                context_instance=RequestContext(request)
                )

    else:
        form = loginForm() # An unbound form
        return render_to_response('login.html',
                {'form': form},
                context_instance=RequestContext(request)
                )


class logoutForm(forms.Form):
     print  

class activityForm(forms.Form):
     print  

class infoForm(forms.Form):

    name_ch = forms.CharField(label=u'姓名(中文)', required=False, help_text='姓名,國籍,身份證號碼,生日 如要修改請與文宣組聯絡', widget=forms.TextInput(attrs={'readonly':'readonly'}))
    nationality = forms.CharField(label=u'國籍', required=False, widget=forms.TextInput(attrs={'readonly':'readonly'}))
    nationalid = forms.CharField(label=u'身份證或護照號碼', required=False, widget=forms.TextInput(attrs={'readonly':'readonly'}))
    birthday = forms.CharField(label=u'西元生日', required=False, widget=forms.TextInput(attrs={'readonly':'readonly'}))

    name_en = forms.RegexField(label=u'姓名(英文)', required=False, regex='^\s*[A-Za-z]{2,},[A-Za-z\s]{2,}$', help_text='有護照就填寫護照上英文姓名,格式:LI,DA FA(李,大發)(姓放前面,然後逗點,然後名)(不要使用\'-\'當分隔符號) <a href="http://www.englishname.org/" target="_blank">姓名英譯查詢</a>')
    mobile = forms.RegexField(label=u'電話(手機)', required=False, regex='^\s*[0-9]{10}\s*$', help_text='(建議填) 活動,服勤通知用, 範例格式: 0937019628 (不要輸入任何不是數字的字元)')
    phone = forms.RegexField(label=u'電話(市話)', required=False, regex='\s*(\([0-9]+\)\s*[0-9]{5,}\s*#?\s*[0-9]{1,}|^[-]+)\s*$',  help_text='範例格式: (02)23066387 (不要使用\'-\'當分隔符號,分機號碼分隔符號是\'#\')')
    zip = forms.RegexField(label=u'郵遞區號', required=True, regex='\s*[0-9]{5}\s*$', help_text='(必填) 請輸入五碼,例如:11049 <a href="http://www.moneymanager.url.tw/台灣3+2郵遞區號查詢系統.htm" target="_blank">查詢五碼郵遞區號</a>')
    address = forms.CharField(label=u'通訊地址', min_length=10, required=True, help_text='(必填) 用於寄送隊訊,隊部刊物', widget=forms.TextInput(attrs={'size':60}))
    email = forms.EmailField(label=u'Email', required=False, help_text='(建議填) 活動,服勤通知用',widget=forms.TextInput(attrs={'size':30}))


    CHOICES_ACT = (('SM', '簡訊',), ('EM', 'Email',))
    notice_activity = forms.MultipleChoiceField(label=u'隊部活動通知方式(例如:服勤提醒)', widget=forms.CheckboxSelectMultiple, choices=CHOICES_ACT, required=False)
    CHOICES_MAJOR = (('PA', '紙本',), ('EM', 'Email',))
    notice_major = forms.MultipleChoiceField(label=u'隊部重點刊物通知方式(例如:隊部年度發行刊物)', widget=forms.CheckboxSelectMultiple, choices=CHOICES_MAJOR, required=False)
    CHOICES_MINOR = (('PA', '紙本',), ('EM', 'Email',))
    notice_minor = forms.MultipleChoiceField(label=u'隊部次重點刊物通知方式(例如:例行性隊訊)', widget=forms.CheckboxSelectMultiple, choices=CHOICES_MINOR, required=False)


    def clean(self):
        data = self.cleaned_data
            
        logging.info(data)
    
        """
        for i in ["name_en", "mobile", "phone", "zip", "address", "email", "act_remind", "major_info", "minor_info"]:
            vars()[i] = data.get(i, None)
            if vars()[i] == "":
                vars()[i] = None
        """

        #oldpasswd = data.get("oldpasswd",None)

        #if( (newpasswd != None) and (passwdHint != None) ):
        #    d = levenshtein(newpasswd.strip(), passwdHint.strip())

        #    if( d < 8 ):
        #        self._errors["passwdHint"] = self.error_class(["新密碼提示字串與新密碼太類似,請重新輸入"])

        return data

def info(request):
     if request.method == 'POST': # If the form has been submitted...
        form = infoForm(request.POST) # A form bound to the POST data

        logging.info('request.POST')
        logging.info(request.POST)
        logging.info('form.data')
        logging.info(form.data)

        if 'previous' in form.data:
            return render_to_response('system.html', {'user':s.user, 'default_disabled':'x'},
                    context_instance=RequestContext(request))

        if form.is_valid(): # All validation rules pass
            data_in = dict(request.POST)                                         
            new_data = s.clean_userdata(data_in)
            if s.update_user(new_data):
                s.get_user(s.user['id'])

                return render_to_response('info.html', {'form':form, 'success':'資料更改成功'}, context_instance=RequestContext(request))
            else:
                return render_to_response('info.html', {'form':form, 'error':'系統錯誤,請稍後再重試一次'}, context_instance=RequestContext(request))
        else: 
            return render_to_response('info.html', {'form':form, 'error':'請檢查欄位', 'user':s.user}, context_instance=RequestContext(request))

   

class sysmainForm(forms.Form):
     print  

def sysmain(request):

    if request.method == 'POST': # If the form has been submitted...
        form = sysmainForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            #      logging.info(form.data)
            fi = str(form.data.items()[0][0])
            f = globals()[fi+'Form']
            
            if fi == 'info':
                # FIXME: use re
                zip = None
                address = None
                mobile = None
                if 'address' in s.user:
                    zip = s.user['address'].split()[0]
                    address = s.user['address'].split()[1]
                if 'mobile' in s.user:
                    if len(s.user['mobile']) == 9 and s.user['mobile'][0] == '9':
                        mobile = str('0'+s.user['mobile'])
                    else:
                        mobile = s.user['mobile']

                d = {}
                for i in ["name_ch", 'nationality', 'nationalid', 'birthday', 'name_en', 'phone', 'email', 'notice_activity', 'notice_major', 'notice_minor']:
                    if i in s.user:
                        d[i] = s.user[i]

                d = dict(d.items()+[('mobile', mobile),('zip',zip),('address',address)])

                return render_to_response(fi+'.html',{'form': f(d),
                    'user': s.user}, context_instance=RequestContext(request))
            else:
                return render_to_response(fi+'.html',{'form': f, 'user': s.user}, context_instance=RequestContext(request))


def levenshtein(s1, s2):
    l1 = len(s1)
    l2 = len(s2)

    matrix = [range(l1 + 1)] * (l2 + 1)
    for zz in range(l2 + 1):
        matrix[zz] = range(zz,zz + l1 + 1)
    for zz in range(0,l2):
        for sz in range(0,l1):
            if s1[sz] == s2[zz]:
                matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz])
            else:
                matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz] + 1)
    return matrix[l2][l1]



class passwdForm(forms.Form):
    min=8
    max=20

    passwdRef = ['ab837122','timchen543']

    oldpasswd = forms.CharField(label=u'舊密碼', min_length=min, max_length=max, help_text='請輸入剛剛用來登入的密碼')
    newpasswd = forms.RegexField(label=u'新密碼', min_length=min, max_length=max, regex='^(?=(?:.*?\d){2})(?=(?:.*?[A-Za-z]){2})\w*$', help_text='新密碼長度至少要為8,不得超過20,至少包含兩個數字(0-9)和兩個英文字母(a-z,A-Z),合乎規格的密碼如:%s(這兩個範例也不能用)' % passwdRef)
    newpasswd2 = forms.CharField(label=u'再次輸入新密碼', min_length=min, max_length=max)
    passwdHint = forms.CharField(label=u'新密碼提示字串', help_text='如果你忘了新設定的密碼,這提示將會出現提醒',max_length=max)

    def clean(self):
        data = self.cleaned_data
        oldpasswd = data.get("oldpasswd",None)
        newpasswd = data.get("newpasswd",None)
        newpasswd2 = data.get("newpasswd2",None)
        passwdHint = data.get("passwdHint",None)

        if oldpasswd == None or newpasswd == None or newpasswd2 == None or passwdHint == None:
            return data

        if oldpasswd != s.user['passwd']:
            # FIXME: clean error immediately
            raise forms.ValidationError(u"舊密碼錯誤")
            return data

        if oldpasswd == newpasswd:
            raise forms.ValidationError(u"新密碼不得與舊密碼一樣")
            return data

        if newpasswd != newpasswd2:
            raise forms.ValidationError(u"新密碼與再次輸入新密碼不一致")
            return data

        for p in self.passwdRef:
            if( newpasswd == p ):
                self._errors["newpasswd"] = self.error_class(['新密碼不得是%s' % self.passwdRef])
        
        if( (newpasswd != None) and (passwdHint != None) ):
            d = levenshtein(newpasswd.strip(), passwdHint.strip())

            if( d < 8 ):
                self._errors["passwdHint"] = self.error_class(["新密碼提示字串與新密碼太類似,請重新輸入"])

        return data

def passwd(request): 
    def returnError(request, form, error):
        return render_to_response('passwd.html',
                {
                    'form': form,
                    'error': error, 
                    },
                context_instance=RequestContext(request)
                )

    if request.method == 'POST': # If the form has been submitted...
        form = passwdForm(request.POST) # A form bound to the POST data

        if 'previous' in form.data:
            d = {'user':s.user}

            if l.status == l.ok :
                d['default_disabled'] = 'x'

            return render_to_response('system.html', d
                , context_instance=RequestContext(request))

        if form.is_valid(): # All validation rules pass
            newpasswd = (request.POST['newpasswd'])
            passwdHint = (request.POST['passwdHint'])

            new_data = {'passwd':newpasswd, 'passwdhint':passwdHint}
            
            l.status = l.ok
            
            if( s.update_user(new_data) ):
                s.get_user(s.user['id'])
                return render_to_response('passwd.html', {'form':form, 'success':'設定成功,下次請用新密碼登錄'}, context_instance=RequestContext(request))
            else:
                return render_to_response('passwd.html', {'form':form, 'error':'系統錯誤,請稍後再重試一次'}, context_instance=RequestContext(request))

        else:
            return render_to_response('passwd.html', {'form':form, 'error':'請檢查欄位'}, context_instance=RequestContext(request))
